package com.tedu.api.list;

import org.junit.Test;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

/**Collection集合下 子集合【叫队列】    包位置：java.util
 * Queue    队列      单端队列
 * Deque    队列      双端队列    "Deque接口--继承--Queue接口"
 * 作用：保存数据，有序存储和处理，功能：数据缓冲或者多线程协调工作！
 *
 * 队列实现类：
 * LinkedList:双向链表
 */
public class QueueAPI {
    // Queue     队列     单端队列
    @Test
    public void testQueue() {
        //创建队列--多态--LinkedList
        Queue<String> queue = new LinkedList<>();
        /**
         * offer()  ----add()一样
         * 作用：入队操作，队尾追加元素
         */

        queue.offer("青花瓷");
        queue.offer("冬眠");
        queue.offer("我的滑板鞋");
        queue.offer("体面");
        System.out.println("Queue队列"+queue);
        /**
         * poll()
         * 作用：出队操作，获取队首元素，并且删除队列中队首
         * peek()
         * 作用：出队操作，获取队首元素，不删除队列中队首
         */
        queue.poll();queue.poll();
        System.out.println("Queue队列:"+queue);
        String str= queue.peek();
        System.out.println("队首元素:"+str);
        System.out.println("Queue队列:"+queue);
        /**
         * 需求：1.遍历对列---while---只遍历一次队列【队列元素消失】
         *      提示：while 条件：拿到队列中总长度  size（）>0
         * 需求：2.遍历队列---增强for---队列元素不消失
         *     提示：for条件：E e：队列
         */
        while(queue.size()>0){  //true:队列总数>0 队列有元素 遍历
            str=queue.poll(); //获取队首，删除队首
            System.out.println("获取队列元素："+str);
        }
        System.out.println("Queue队列元素："+queue);
        /**
         * 需求：2.遍历队列--增强for--队列元素不消失
         *      提示：for  条件：E e 数组泛型/集合泛型：数组引用/集合引用
         */
        for(String e:queue){
            System.out.println("队列元素："+e);
        }
        System.out.println("Queue队列"+queue);
    }
    //Deque    队列    双端队列---继承---单端队列
    @Test
    public void testDeque(){
        //创建Deque  双端队列   方法基本一致，部分方法不一致
        Deque<String> deque=new LinkedList<>();
        deque.offer("任");   deque.offer("王");
        deque.offer("毛");   deque.offer("那" );
        System.out.println("双端队列"+deque);
        //offerFirst()  队首添加元素    offerLast()队尾添加元素
        deque.offerFirst("蔡徐坤");    deque.offerFirst("薛之谦");
        System.out.println("双端队列【首尾添加元素】："+deque);
        //getFirst() 获取队首    getLast() 获取队尾 【单端：peek类似】
        System.out.println("获取队列中队首："+deque.getFirst());
        System.out.println("获取队列中队尾："+deque.getFirst());
        //poolFirst() 获取队首，会删除队列中队首  【单端：poll类似】
        //poolLast() 获取队尾，会删除队列中队尾
        String xue=deque.pollLast(); //删除“薛之谦”元素  队列---队首
        System.out.println("队尾元素："+xue);
        System.out.println("双端队列："+deque);
    }
    /**
     * 找结构：业务中如果有后退【撤销】情况使用
     */
    @Test
    public void testStack(){
        //闯将双端队列
        Deque<String> stack=new LinkedList<>();
        /**
         * push()   Deque  独有方法--支持栈结构
         * ---offer---add：Collection接口  【添加】
         * 作用：【添加：往栈压入一个元素】压栈操作
         */
        stack.push("夯大力");
        stack.push("恶搞之家");
        stack.push("喜羊羊");
        stack.push("魔法大厦");
        System.out.println("栈结构："+stack);
        /**
         * pop()  出栈一个尾元素  - -pollLast
         */
        String last=stack.pop();
        System.out.println("出栈尾元素"+last);
        System.out.println("栈结构"+stack);
        //面试题：pop poll peek的使用区别？
        //1.pop() 方法通常与栈操作相关联，它会删除并返回链表中的第一个元素（栈顶元素）。
        //如果链表为空，pop() 方法会抛出NoSuchElementException异常。
        //这个方法在功能上等同于removeFirst()方法
        //2.poll() 方法通常与队列操作相关联，它也会删除并返回链表中的第一个元素（队首元素）。
        //与pop()不同，如果链表为空，poll() 方法会返回null，而不是抛出异常。
        //这个方法直接调用unlinkFirst()方法。
        //3.peek() 方法与poll()方法类似，但它只是返回链表中的第一个元素（队首元素），并不删除它。
        //如果链表为空，peek() 方法同样会返回null。

         // 需求1：遍历栈结构---while---元素出栈，队列元素需要清空
         while(stack.size()>0){
            String i = stack.pop();//获取、然后删除
            System.out.println("获取队列元素:"+i);
         }
            System.out.println("获取stack队列："+stack);

         //需求2：遍历栈结构--增强for--元素遍历成功，队列元素不变
        for(String e:stack){
            System.out.println("获取队列元素"+e);
        }
            System.out.println("获取stack队列"+stack);
    }
}